package com.ruoyi.management.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.management.base.utils.DateUtils;
import com.ruoyi.management.dao.mapper.BillingMapper;
import com.ruoyi.management.dao.mapper.WxMapper;
import com.ruoyi.management.pojo.entity.*;
import com.ruoyi.management.pojo.param.KtParam;
import com.ruoyi.management.pojo.param.KtParam1;
import com.ruoyi.management.pojo.po.*;
import com.ruoyi.management.pojo.vo.*;
import com.ruoyi.management.service.BillingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.stream.Collectors;


@Slf4j
@Service
public class BillingImpl implements BillingService {

    @Autowired
    private BillingMapper billingMapper;
    @Autowired
    private WxMapper wxMapper;


//    @Override
//    public List<BillingVO> compute(Date selectTime,String qymc) {
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        log.info("接收到的日期参数: {}", sdf.format(selectTime));
//            List<KhbhDbbh> khbhList = billingMapper.selectQldbzymx1(selectTime,qymc);
////        List<String> khbhList = Arrays.asList(
////                 "kh25041394824", "kh25051691200"
////        );
//        List<BillingVO> allResults = new ArrayList<>();
//        for (KhbhDbbh kd : khbhList) {
//            List<BillingVO> result = Ccompute(selectTime, kd);
//            allResults.addAll(result);
//        }
//        for (BillingVO vo : allResults) {
//            String dbbh = vo.getDbbh();
//            BigDecimal dbdj = billingMapper.selectDbdjByDbbh(dbbh);
//            if (dbdj != null) {
//                vo.setDbdj(dbdj); // 确保 BillingVO 有 setDbdj 方法
//            }
//
//            // 计算金额：zzdl * dbdj
//            BigDecimal zzdl = vo.getZzdl();
//            if (zzdl != null && dbdj != null) {
//                BigDecimal amount = zzdl.multiply(dbdj);
//                vo.setAmount(amount);
//            }
//        }
//        // 分组聚合逻辑
//        Map<String, BillingVO> groupedMap = new LinkedHashMap<>();
//        for (BillingVO vo : allResults) {
//            String key = vo.getKhbh();
//
//            if (!groupedMap.containsKey(key)) {
//                groupedMap.put(key, vo);
//            } else {
//                BillingVO existing = groupedMap.get(key);
//
//                // 合并非数值字段（fjh、zt等），不同值用逗号拼接
//                mergeFields(existing, vo, BillingVO::getFjh, BillingVO::setFjh);
//                mergeFields(existing, vo, BillingVO::getZt, BillingVO::setZt);
//                mergeFields(existing, vo, BillingVO::getDbbh, BillingVO::setDbbh);
//                mergeFields(existing, vo, BillingVO::getZzdl, BillingVO::setZzdl);
//                mergeFields(existing, vo, BillingVO::getAmount, BillingVO::setAmount);
//                // 可继续扩展其他字段...
//
//                // 数值字段累加
//                existing.setZzdl(existing.getZzdl().add(vo.getZzdl()));
//                existing.setAmount(existing.getAmount().add(vo.getAmount()));
//            }
//        }
//        // 最终结果
//        List<BillingVO> finalResult = new ArrayList<>(groupedMap.values());
//
//        // 设置 zdl 和 zAmount（可选）
//        for (BillingVO vo : finalResult) {
//            vo.setZzdl(vo.getZzdl());
//            vo.setAmount(vo.getAmount());
//            vo.setServiceFee(BigDecimal.ZERO);
//            vo.setTotal(vo.getAmount());
//            vo.setPayStatus(1);
//            vo.setContractStatus(1);
//            vo.setInvoiceStatus(1);
//            vo.setQyStatus(1);
//            vo.setDownloadUrl("");
//        }
//
//        return finalResult;
//    }

    @Override
    public List<Qldbykhmx> compute(String month, String qymc,String tgszt,String hkzt,String hklx) {
        String[] values = tgszt.split(",");
        if (month==null || month==""){
            List<Qldbykhmx> billingVOList = billingMapper.selectBillingList1(qymc, values,hkzt);
            return billingVOList;
        }
        Date date=DateUtils.getFirstDayOfMonth(month);
        List<Qldbykhmx> billingVOList = billingMapper.selectBillingList(date, qymc, values,hkzt,hklx);
        return billingVOList;
    }

//    @Override
//    public List<TenantBillingVO> electricity(String khbh,Date mouth) {
//        LocalDate lastMonth = LocalDate.now().minusMonths(1);
//        Date selectTime = localDateToDate(lastMonth);
//        List<KhbhDbbh> khbhList=billingMapper.selectQldbzymx2(khbh, mouth);
//        List<BillingVO> allResults = new ArrayList<>();
//        for (KhbhDbbh kd : khbhList) {
//            List<BillingVO> result = Ccompute(selectTime, kd);
//            allResults.addAll(result);
//        }
//        return mergeBillingVos(allResults);
//    }

    @Override
    public List<QLdbzymxVO> selectDbList(String zt) {
        return Collections.emptyList();
    }

    @Override
    public Boolean ammeterZyStatus(QLdbzymxVO qLdbzymxVO) {
        return billingMapper.ammeterZyStatus(qLdbzymxVO);
    }

    @Override
    public List<DbdfVO> selectMeterFeeList(String month, String zt) {
        Date lastDate = DateUtils.getFirstDayOfMonth(month);
        return billingMapper.selectMeterFeeList(zt, lastDate);
    }

    @Override
    public List<DbdfVO> selectMeterFeeListCheck(String month, String zt) {
        Date lastDate = DateUtils.getFirstDayOfMonth(month);
        return billingMapper.selectMeterFeeListCheck(zt, lastDate);
    }




    @Override
    public List<Dbydydfvckkh> selectydkh(String zt, String month, Integer dflx) {
        if (dflx==1){
            Date date=DateUtils.getFirstDayOfMonth(month);
            return billingMapper.selectydkh(zt,date);
        }
        if (dflx==2){
            Date date=DateUtils.getFirstDayOfMonth(month);
            return billingMapper.selectydkhc(zt,date);
        }
        if (dflx==3){
            Date date=DateUtils.getFirstDayOfMonth(month);
            return billingMapper.selectydkhkt(zt,date);
        }
        return Collections.emptyList();
    }

    @Override
    public List<ZTVO> selectZt(String month, String tgszt) {
        Date date=DateUtils.getFirstDayOfMonth(month);
        String[] values = tgszt.split(",");
        if ("1".equals(tgszt)){
            return billingMapper.selectzt2(date);
        }
        return billingMapper.selectzt1(values,date);
    }

    @Override
    public DbkhhkyVO monthReceivable(String month, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.monthReceivable(date, values, zt);
    }

    @Override
    public DbkhhkyVO yearDelay(String year, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Integer date=Integer.parseInt(year.toString());
        return billingMapper.yearDelay(date, values, zt);
    }

    @Override
    public List<Qldbykhmx> monthReceivablemx(String month, String tgszt, String zt, String qymc) {
        String[] values = tgszt.split(",");
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.monthReceivablemx(date, values, zt, qymc);
    }

    @Override
    public List<Qldbykhmx> yearDelaymx(String tgszt, String zt) {
        String[] values = tgszt.split(",");
        return billingMapper.yearDelaymx(values, zt);
    }

    @Override
    public DbkhhkyVO received(String month, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.received(date, values, zt);
    }

    @Override
    public List<QldbysjmxVO> receivedmx(String month, String tgszt, String zt, String qymc) {
        String[] values = tgszt.split(",");
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.receivedmx(values,date, zt, qymc);
    }

    @Override
    public List<QldbysjmxVO> Invoiced(String month, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.Invoiced(values,date, zt);
    }

    @Override
    public DbkhhkyVO unInvoiced(String year, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Integer date=Integer.parseInt(year.toString());
        return billingMapper.unInvoiced(date, values, zt);
    }

    @Override
    public List<QldbysjmxVO> unInvoicedmx(String year, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Integer date=Integer.parseInt(year.toString());
        return billingMapper.unInvoicedmx(date, values, zt);
    }

    @Override
    public DbkhhsjbVO customer(String khbh,String zt) {
        return billingMapper.customer(khbh,zt);
    }

    @Override
    public List<Qldbykhmx> customerMx(String zt, String khbh) {
        return billingMapper.customerMx(zt, khbh);
    }

    @Override
    public List<QldbysjmxVO> customerReceived(String zt, String khbh) {
        return billingMapper.customerReceived(zt, khbh);
    }

    @Override
    public List<Qldbykp> customerInvoiced(String zt, String khbh) {
        return billingMapper.customerInvoiced(zt, khbh);
    }

    @Override
    public List<Qldbykhmx> yearDelayPast(String year, String tgszt, String zt) {
        String[] values = tgszt.split(",");
        Integer date=Integer.parseInt(year.toString());
        return billingMapper.yearDelaymx1(date, values, zt);
    }

    @Override
    public Boolean airConditioning(List<AirConditioningParam> airConditioningParams) {
        //对空调设备进行批量插入
        for (AirConditioningParam bill : airConditioningParams) {
            Qldbakt qldbakt=new Qldbakt();
            qldbakt.setZt(bill.getZt());
            qldbakt.setQymc(bill.getQymc());
            qldbakt.setNf(bill.getNf());
            qldbakt.setYf(bill.getYf());
            qldbakt.setHklx("空调费");
            qldbakt.setDbs(bill.getDbs());
            qldbakt.setKtfje(bill.getKtfje());
            qldbakt.setYx(1);
            qldbakt.setTname(bill.getTname());
            qldbakt.setTimestamp(new Date());
            Boolean a=billingMapper.insertQldbakt(qldbakt);
            if (!Boolean.TRUE.equals(a)){
                throw new RuntimeException("插入失败：客户编号=" + qldbakt.getKhbh() + "，客户名称=" + qldbakt.getQymc());
            }
        }
        return true;
    }

    @Override
    public AirConditioningParam airConditioningMatch(String month, String zt) {
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.airConditioningMatch(date, zt);
    }

    @Override
    public List<Qldbakt> airConditioningList(String month, String zt) {
        Date date=DateUtils.getFirstDayOfMonth(month);
        return billingMapper.airConditioningList(date, zt);
    }

//    @Override
//    public Boolean airConditioning1(KtParam ktParam) {
//        String jsonString = ktParam.getDataRows();
//        try {
//            ObjectMapper objectMapper = new ObjectMapper();
//            List<KtParam1> ktParamList = objectMapper.readValue(
//                    jsonString,
//                    new TypeReference<List<KtParam1>>() {}
//            );
//
//            // 转换日期格式并构建待插入列表
//            List<KtParam1> insertList = new ArrayList<>();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
//            SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
//            SimpleDateFormat fullDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//
//            // 解析前端传入的月份参数
//            Date monthDate = monthFormat.parse(ktParam.getDate());
//            Calendar calendar = Calendar.getInstance();
//            calendar.setTime(monthDate);
//
//            // 获取当月第一天和最后一天
//            calendar.set(Calendar.DAY_OF_MONTH, 1);
//            Date firstDayOfMonth = calendar.getTime();
//            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
//            Date lastDayOfMonth = calendar.getTime();
//
//            // 优化：批量查询房间信息和时间信息
//            Map<String, Qldbakt> roomInfoMap = new HashMap<>();
//
//            // 先收集所有需要查询的房间号
//            Set<String> roomNumbers = ktParamList.stream()
//                    .map(KtParam1::getRoom)
//                    .collect(Collectors.toSet());
//
//            // 一次性查询所有房间的完整信息
//            if (!roomNumbers.isEmpty()) {
//                List<Qldbakt> roomInfoList = billingMapper.selectKtByRooms(new ArrayList<>(roomNumbers), ktParam.getZt());
//                roomInfoMap = roomInfoList.stream()
//                        .collect(Collectors.toMap(
//                                Qldbakt::getRoom,
//                                info -> info,
//                                (existing, replacement) -> existing
//                        ));
//            }
//
//            // 第一步：插入基本空调数据
//            for (KtParam1 param : ktParamList) {
//                Qldbakt roomInfo = roomInfoMap.get(param.getRoom());
//                if (roomInfo == null) {
//                    System.out.println("未找到匹配记录，跳过当前记录: " + param.getRoom());
//                    continue;
//                }
//
//                try {
//                    Date date = sdf.parse(param.getDate());
//
//                    KtParam1 airData = new KtParam1();
//                    airData.setTimestamp(date);
//                    airData.setRoom(param.getRoom());
//                    airData.setQymc(roomInfo.getQymc());
//                    airData.setKhbh(roomInfo.getKhbh());
//                    airData.setZt(ktParam.getZt());
//                    airData.setFloor(param.getFloor());
//                    airData.setTotalPower(param.getTotalPower());
//                    airData.setTotalCost(param.getTotalCost());
//                    airData.setCreateTime(new Date());
//
//                    insertList.add(airData);
//                } catch (ParseException e) {
//                    System.err.println("日期解析失败: " + param.getDate());
//                    e.printStackTrace();
//                }
//            }
//
//            // 执行第一次批量插入
//            boolean firstInsertResult = false;
//            if (!insertList.isEmpty()) {
//                firstInsertResult = billingMapper.batchInsertQldbkt(insertList) > 0;
//                System.out.println("第一次插入结果: " + firstInsertResult);
//            } else {
//                System.out.println("没有可插入的基本空调数据");
//                return false;
//            }
//
//            // 第二步：计算有效数据并进行二次插入
//            List<Qldbakt> calculatedInsertList = new ArrayList<>();
//
//            // 遍历每个房间，计算符合条件的总电量和总费用
//            for (String roomNumber : roomNumbers) {
//                Qldbakt roomInfo = roomInfoMap.get(roomNumber);
//                if (roomInfo == null) {
//                    System.out.println("未找到匹配记录，跳过计算: " + roomNumber);
//                    continue;
//                }
//
//                // 解析启用时间和退用时间
//                Date qysj = null; // 启用时间
//                Date tysj = null; // 退用时间
//
//                    if (roomInfo.getQysj() != null) {
//                        // 如果getQysj()返回Date类型，直接赋值
//                        qysj = roomInfo.getQysj();
//                    }
//
//                    if (roomInfo.getTysj() != null) {
//                        // 如果getTysj()返回Date类型，直接赋值
//                        tysj = roomInfo.getTysj();
//                    }
//
//                // 新增逻辑：判断启用时间是否晚于当前月份，如果是则跳过该房间
//                if (qysj != null && isMonthGreater(qysj, monthDate)) {
//                    System.out.println("启用时间晚于当前月份，跳过房间: " + roomNumber);
//                    continue;
//                }
//
//                // 计算有效日期范围
//                Date effectiveStartDate = firstDayOfMonth;
//                Date effectiveEndDate = lastDayOfMonth;
//
//                // 判断启用时间是否在当月
//                if (qysj != null && isSameMonth(qysj, monthDate)) {
//                    effectiveStartDate = qysj;
//                }
//
//                // 判断退用时间是否在当月
//                if (tysj != null && isSameMonth(tysj, monthDate)) {
//                    effectiveEndDate = tysj;
//                }
//
//                // 确保开始日期不晚于结束日期
//                if (effectiveStartDate.after(effectiveEndDate)) {
//                    System.out.println("开始日期晚于结束日期，跳过计算: " + roomNumber);
//                    continue;
//                }
//
//                // 获取当月该房间的所有记录
//                List<KtParam1> roomRecords = getRecordsByRoomAndMonth(roomNumber, ktParam.getDate());
//
//                // 计算符合条件的总电量和总费用
//                BigDecimal totalPowerSum = BigDecimal.ZERO;
//                BigDecimal totalCostSum = BigDecimal.ZERO;
//
//                for (KtParam1 record : roomRecords) {
//
//                        Date recordDate = record.getTimestamp();
//
//                        // 如果记录日期在有效范围内，累加电量和费用
//                        if (!recordDate.before(effectiveStartDate) && !recordDate.after(effectiveEndDate)) {
//                            if (record.getTotalPower() != null) {
//                                totalPowerSum = totalPowerSum.add(record.getTotalPower());
//                            }
//                            if (record.getTotalCost() != null) {
//                                totalCostSum = totalCostSum.add(record.getTotalCost());
//                            }
//                        }
//                }
//
//                // 创建二次插入的数据（使用当月第一天作为时间戳）
//                Qldbakt calculatedData = new Qldbakt();
//                calculatedData.setZt(ktParam.getZt());
//                calculatedData.setQymc(roomInfo.getQymc());
//                calculatedData.setKhbh(roomInfo.getKhbh());
//                // 拆分字符串获取年份部分
//                String yearStr = ktParam.getDate().split("-")[0]; // 结果："2025"
//                // 转换为整数
//                int year = Integer.parseInt(yearStr); // 结果：2025
//                // 拆分字符串获取年份部分
//                String monthStr = ktParam.getDate().split("-")[1]; // 结果："2025"
//                // 转换为整数
//                int month = Integer.parseInt(monthStr); // 结果：2025
//                calculatedData.setNf(year);
//                calculatedData.setYf(month);
//                calculatedData.setHklx("空调费");
//                calculatedData.setYx(1);
//                calculatedData.setDbs(totalPowerSum);
//                calculatedData.setKtfje(totalCostSum);
//                calculatedData.setAa(BigDecimal.ZERO);
//                calculatedData.setAb(BigDecimal.ZERO);
//                calculatedData.setTname(ktParam.getTname());
//                calculatedData.setTimestamp(new Date());
//                calculatedInsertList.add(calculatedData);
//            }
//
//            // 执行第二次批量插入
//            if (!calculatedInsertList.isEmpty()) {
//                boolean secondInsertResult = billingMapper.batchInsertQldbktCalculated(calculatedInsertList) > 0;
//                System.out.println("第二次插入结果: " + secondInsertResult);
//                return firstInsertResult && secondInsertResult;
//            } else {
//                System.out.println("没有可插入的计算后数据");
//                return firstInsertResult;
//            }
//        } catch (JsonProcessingException e) {
//            System.err.println("JSON解析失败: " + jsonString);
//            e.printStackTrace();
//            return false;
//        } catch (Exception e) {
//            System.err.println("发生未知异常");
//            e.printStackTrace();
//            return false;
//        }
//    }

    @Override
    public Integer airConditioning1(KtParam ktParam) {
        String jsonString = ktParam.getDataRows();
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            List<KtParam1> ktParamList = objectMapper.readValue(
                    jsonString,
                    new TypeReference<List<KtParam1>>() {}
            );

            // 转换日期格式并构建待插入列表
            List<KtParam1> insertList = new ArrayList<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
            SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");

            // 解析前端传入的月份参数
            Date monthDate = monthFormat.parse(ktParam.getDate());
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(monthDate);

            // 获取当月第一天和最后一天
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            Date firstDayOfMonth = calendar.getTime();
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            Date lastDayOfMonth = calendar.getTime();

            // 批量查询房间信息和时间信息，按房间号分组存储多个租户
            Map<String, List<Qldbakt>> roomTenantsMap = new HashMap<>();

            // 先收集所有需要查询的房间号
            Set<String> roomNumbers = ktParamList.stream()
                    .map(KtParam1::getRoom)
                    .collect(Collectors.toSet());

            // 一次性查询所有房间的完整信息
            if (!roomNumbers.isEmpty()) {
                List<Qldbakt> roomInfoList = billingMapper.selectKtByRooms(new ArrayList<>(roomNumbers), ktParam.getZt());

                List<Qldbakt> distinctRoomInfoList = new ArrayList<>();
                Set<String> uniqueKeys = new HashSet<>();

                for (Qldbakt roomInfo : roomInfoList) {
                    // 使用fjh和khbh组合作为唯一键
                    String key = roomInfo.getRoom() + "_" + roomInfo.getKhbh();
                    if (!uniqueKeys.contains(key)) {
                        uniqueKeys.add(key);
                        distinctRoomInfoList.add(roomInfo);
                    }
                }
                // 按房间号分组，并按启用时间排序
                roomTenantsMap = distinctRoomInfoList.stream()
                        .collect(Collectors.groupingBy(
                                Qldbakt::getRoom,
                                Collectors.collectingAndThen(
                                        Collectors.toList(),
                                        list -> {
                                            // 按启用时间排序，确保租户顺序正确
                                            list.sort(Comparator.comparing(Qldbakt::getQysj));
                                            return list;
                                        }
                                )
                        ));
            }

            // 第一步：插入基本空调数据
            for (KtParam1 param : ktParamList) {
                String roomNumber = param.getRoom();
                List<Qldbakt> tenants = roomTenantsMap.getOrDefault(roomNumber, Collections.emptyList());
                if (tenants.isEmpty()) {
                    System.out.println("未找到房间记录，跳过: " + roomNumber);
                    continue;
                }

                try {
                    Date recordDate = sdf.parse(param.getDate());
                    // 找到该日期对应的租户
                    Qldbakt matchedTenant = findMatchedTenant(tenants, recordDate);
                    if (matchedTenant == null) {
                        System.out.println("房间" + roomNumber + "在日期" + recordDate + "无匹配租户，跳过");
                        continue;
                    }

                    KtParam1 airData = new KtParam1();
                    airData.setTimestamp(recordDate);
                    airData.setRoom(roomNumber);
                    airData.setQymc(matchedTenant.getQymc());
                    airData.setKhbh(matchedTenant.getKhbh());
                    airData.setZt(ktParam.getZt());
                    airData.setFloor(param.getFloor());
                    airData.setTotalPower(param.getTotalPower());
                    airData.setTotalCost(param.getTotalCost());
                    airData.setCreateTime(new Date());

                    insertList.add(airData);
                } catch (ParseException e) {
                    System.err.println("日期解析失败: " + param.getDate());
                    e.printStackTrace();
                }
            }

            try {
                // 执行第一次批量插入
                boolean firstInsertResult = false;
                if (!insertList.isEmpty()) {
                    firstInsertResult = billingMapper.batchInsertQldbkt(insertList) > 0;
                    System.out.println("第一次插入结果: " + firstInsertResult);
                } else {
                    System.out.println("没有可插入的基本空调数据");
                    return 2;
                }
            }catch (DuplicateKeyException e) {
                return 3;
            }


            // 第二步：计算有效数据并进行二次插入
            List<Qldbakt> calculatedInsertList = new ArrayList<>();

            // 遍历每个房间，计算符合条件的总电量和总费用
            for (String roomNumber : roomNumbers) {
                List<Qldbakt> tenants = roomTenantsMap.getOrDefault(roomNumber, Collections.emptyList());
                if (tenants.isEmpty()) {
                    System.out.println("未找到房间记录，跳过计算: " + roomNumber);
                    continue;
                }

                // 获取当月该房间的所有记录
                List<KtParam1> roomRecords = getRecordsByRoomAndMonth(roomNumber, ktParam.getDate(), ktParam.getZt());

                // 遍历每个租户，分别计算
                for (Qldbakt tenant : tenants) {
                    Date qysj = tenant.getQysj();
                    Date tysj = tenant.getTysj();

                    // 判断启用时间是否晚于当前月份，如果是则跳过该租户
                    if (qysj != null && isMonthGreater(qysj, monthDate)) {
                        System.out.println("租户" + tenant.getKhbh() + "启用时间晚于当前月份，跳过");
                        continue;
                    }

                    // 计算该租户在当前月份的有效日期范围
                    Date effectiveStartDate = getEffectiveStartDate(qysj, firstDayOfMonth);
                    Date effectiveEndDate = getEffectiveEndDate(tysj, lastDayOfMonth);

                    // 确保开始日期不晚于结束日期
                    if (effectiveStartDate.after(effectiveEndDate)) {
                        System.out.println("租户" + tenant.getKhbh() + "的开始日期晚于结束日期，跳过计算");
                        continue;
                    }

                    // 计算符合条件的总电量和总费用
                    BigDecimal totalPowerSum = BigDecimal.ZERO;
                    BigDecimal totalCostSum = BigDecimal.ZERO;

                    for (KtParam1 record : roomRecords) {
                        Date recordDate = record.getTimestamp();

                        // 如果记录日期在有效范围内，累加电量和费用
                        if (!recordDate.before(effectiveStartDate) && !recordDate.after(effectiveEndDate)) {
                            if (record.getTotalPower() != null) {
                                totalPowerSum = totalPowerSum.add(record.getTotalPower());
                            }
                            if (record.getTotalCost() != null) {
                                totalCostSum = totalCostSum.add(record.getTotalCost());
                            }
                        }
                    }

                    // 创建二次插入的数据
                    Qldbakt calculatedData = new Qldbakt();
                    calculatedData.setZt(ktParam.getZt());
                    calculatedData.setQymc(tenant.getQymc());
                    calculatedData.setKhbh(tenant.getKhbh());
                    // 拆分字符串获取年份和月份
                    String[] dateParts = ktParam.getDate().split("-");
                    int year = Integer.parseInt(dateParts[0]);
                    int month = Integer.parseInt(dateParts[1]);
                    calculatedData.setNf(year);
                    calculatedData.setYf(month);
                    calculatedData.setHklx("空调费");
                    calculatedData.setYx(1);
                    calculatedData.setDbs(totalPowerSum);
                    calculatedData.setKtfje(totalCostSum);
                    calculatedData.setAa(BigDecimal.ZERO);
                    calculatedData.setAb(BigDecimal.ZERO);
                    calculatedData.setTname(ktParam.getTname());
                    calculatedData.setTimestamp(new Date());
                    calculatedInsertList.add(calculatedData);
                }
            }
            // 新增：按 nf、yf、khbh、zt 分组聚合，求和 dbs 和 ktfje
            Map<String, Qldbakt> aggregatedMap = new HashMap<>();
            for (Qldbakt data : calculatedInsertList) {
                // 生成唯一分组键：四字段拼接（确保相同组合的记录被分到一组）
                String groupKey = data.getNf() + "_" + data.getYf() + "_" + data.getKhbh() + "_" + data.getZt();

                if (aggregatedMap.containsKey(groupKey)) {
                    // 已存在相同分组，累加 dbs 和 ktfje
                    Qldbakt existing = aggregatedMap.get(groupKey);
                    existing.setDbs(existing.getDbs().add(data.getDbs())); // 电量求和
                    existing.setKtfje(existing.getKtfje().add(data.getKtfje())); // 费用求和
                } else {
                    // 新分组，复制数据到新对象（避免引用冲突）
                    Qldbakt aggregatedData = new Qldbakt();
                    aggregatedData.setNf(data.getNf());
                    aggregatedData.setYf(data.getYf());
                    aggregatedData.setKhbh(data.getKhbh());
                    aggregatedData.setZt(data.getZt());
                    aggregatedData.setQymc(data.getQymc()); // 保留租户名称（若有重复可按需处理）
                    aggregatedData.setHklx(data.getHklx());
                    aggregatedData.setYx(data.getYx());
                    aggregatedData.setDbs(data.getDbs()); // 初始电量
                    aggregatedData.setKtfje(data.getKtfje()); // 初始费用
                    aggregatedData.setAa(data.getAa());
                    aggregatedData.setAb(data.getAb());
                    aggregatedData.setTname(data.getTname());
                    aggregatedData.setTimestamp(data.getTimestamp());
                    aggregatedMap.put(groupKey, aggregatedData);
                }
            }

            // 转换为聚合后的列表
            List<Qldbakt> aggregatedList = new ArrayList<>(aggregatedMap.values());
            try {
                // 执行第二次批量插入
                if (!calculatedInsertList.isEmpty()) {
                    boolean secondInsertResult = billingMapper.batchInsertQldbktCalculated(aggregatedList) > 0;
                    System.out.println("第二次插入结果: " + secondInsertResult);
                    return 1;
                } else {
                    System.out.println("没有可插入的计算后数据");
                    return 2;
                }
            }catch (DuplicateKeyException e) {
                return 3;
            }
        } catch (JsonProcessingException e) {
            System.err.println("JSON解析失败: " + jsonString);
            e.printStackTrace();
            return 2;
        } catch (Exception e) {
            System.err.println("发生未知异常");
            e.printStackTrace();
            return 2;
        }
    }

    @Override
    public Boolean powerSupplyBureau(String zt, String date, BigDecimal wjzjea) {
        Date date1=DateUtils.getFirstDayOfMonth(date);
        Boolean a=billingMapper.powerSupplyBureau(zt,date1,wjzjea);
        return a;
    }

    @Override
    public Boolean payment(String hkid,BigDecimal zhkje,String tname) {
        log.info("缴费后数据处理");
        // 按逗号分割
        String[] numberStrArray = hkid.split(",");

        // 转换为整数数组
        int[] numbers = new int[numberStrArray.length];
        for (int i = 0; i < numberStrArray.length; i++) {
            // 去除可能的空格并转换为整数
            numbers[i] = Integer.parseInt(numberStrArray[i].trim());
        }
        List<Qldbykhmx> qldbykhmx = billingMapper.payment(numbers);
        if (qldbykhmx==null || qldbykhmx.isEmpty()) {return  false;}
        for (Qldbykhmx qdsx : qldbykhmx){
            QldbysjmxVO f1 = new QldbysjmxVO();
            f1.setZt(qdsx.getZt());
            f1.setQymc(qdsx.getQymc());
            f1.setKhbh(qdsx.getKhbh());
            f1.setHkid(qdsx.getHkid());
            f1.setNf(qdsx.getNf());
            f1.setYf(qdsx.getYf());
            f1.setHklx(qdsx.getHklx());
            f1.setHkrq(qdsx.getHkrq());
            f1.setHkks(qdsx.getHkks());
            f1.setHkjs(qdsx.getHkjs());
            f1.setHkzt("已收款");
            f1.setHkje(qdsx.getHkje());
            f1.setYsje(qdsx.getHkje());
            BigDecimal wsje = qdsx.getHkje().subtract(qdsx.getHkje());
            f1.setWsje(wsje);
            f1.setZnysje(qdsx.getZnysje());
            f1.setSjrq(new Date());
            f1.setTname(tname);
            f1.setTimestamp(new Date());
            //新增已收明细表记录qldbysjmx
            Boolean a = billingMapper.insertQldbysjmx(f1);
            if (!a){
                return false;
            }
            Qldbykhmx q1=new Qldbykhmx();
            q1.setHkid(qdsx.getHkid());
            q1.setHkzt("已收款");
            q1.setYsje(qdsx.getHkje());
            q1.setWsje(BigDecimal.ZERO);
            q1.setSjrq(new Date());
            //更新应收表qldbykhmx
            Boolean b = billingMapper.updateQldbykhmx(q1);
            if (!b){
                return false;
            }
        }

//        QldbqyinfoPO q2=billingMapper.selectQldbqyinfo(qldbykhmx.getZt(),qldbykhmx.getKhbh());
//        QldbqyinfoPO q3=new QldbqyinfoPO();
//        q3.setZt(q2.getZt());
//        q3.setKhbh(q2.getKhbh());
//        q3.setYszje(q2.getYszje().add(ysje));
//        q3.setWszje(q2.getWszje().subtract(ysje));
//        q3.setZnysje(q2.getZnysje().add(sznje));
//        //更新客户数据总表qldbqyinfo
//        Boolean c = billingMapper.updateQldbqyinfo(q3);
//        if (!c){return false;}
        return true;
    }

    @Override
    public List<QldbysjmxVO> tenantysmx1(String month,String qymc, String zt,String tgszt) {
        String[] values = tgszt.split(",");
            Date date=DateUtils.getFirstDayOfMonth(month);
            List<QldbysjmxVO> qldbyczmxList = billingMapper.tenantysmx11(qymc, zt,date,values);
        return qldbyczmxList;
    }

    @Override
    public List<QldbysjmxVO> tenantysmx11(String month, String qymc, String zt,String tgszt) {
        String[] values = tgszt.split(",");
        Date date=DateUtils.getFirstDayOfMonth(month);
        List<QldbysjmxVO> qldbyczmxList = billingMapper.tenantysmxje(qymc, zt,date,values);
        return qldbyczmxList;
    }

    @Override
    public List<Dbysdba> tenantqfysmx(String qymc, String zt,String tgszt,Integer status) {
        String[] values = tgszt.split(",");
        List<Dbysdba> qldbyczmxList = billingMapper.tenantqfysmx(qymc,zt,values,status);
        return qldbyczmxList;
    }


    // 根据日期找到匹配的租户
    private Qldbakt findMatchedTenant(List<Qldbakt> tenants, Date date) {
        for (Qldbakt tenant : tenants) {
            Date qysj = tenant.getQysj();
            Date tysj = tenant.getTysj();

            // 检查日期是否在当前租户的租赁期间内
            boolean isAfterQysj = (qysj == null) || !date.before(qysj);
            boolean isBeforeTysj = (tysj == null) || !date.after(tysj);

            if (isAfterQysj && isBeforeTysj) {
                return tenant;
            }
        }
        return null;
    }

    // 计算有效开始日期
    private Date getEffectiveStartDate(Date qysj, Date firstDayOfMonth) {
        if (qysj == null) {
            return firstDayOfMonth;
        }
        // 如果启用时间在当月之后，则从启用时间开始，否则从当月第一天开始
        return qysj.after(firstDayOfMonth) ? qysj : firstDayOfMonth;
    }

    // 计算有效结束日期
    private Date getEffectiveEndDate(Date tysj, Date lastDayOfMonth) {
        if (tysj == null) {
            return lastDayOfMonth;
        }
        // 如果退租时间在当月之前，则从退租时间结束，否则到当月最后一天结束
        return tysj.before(lastDayOfMonth) ? tysj : lastDayOfMonth;
    }

    // 判断两个日期是否在同一个月
    private boolean isSameMonth(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);
        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
    }

    // 判断date1的月份是否大于date2的月份
    private boolean isMonthGreater(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);

        if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) {
            return true;
        } else if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) {
            return false;
        } else {
            return cal1.get(Calendar.MONTH) > cal2.get(Calendar.MONTH);
        }
    }

    // 获取指定房间和月份的所有记录
    private List<KtParam1> getRecordsByRoomAndMonth(String roomNumber, String month,String zt) {
        Date date = DateUtils.getFirstDayOfMonth(month);
        return billingMapper.selectRecordsByRoomAndMonth(roomNumber, date,zt);
    }
//
//    // 判断两个日期是否在同一个月
//    private boolean isSameMonth(Date date1, Date date2) {
//        Calendar cal1 = Calendar.getInstance();
//        Calendar cal2 = Calendar.getInstance();
//        cal1.setTime(date1);
//        cal2.setTime(date2);
//        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
//                cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
//    }
//
//    // 判断date1的月份是否大于date2的月份
//    private boolean isMonthGreater(Date date1, Date date2) {
//        Calendar cal1 = Calendar.getInstance();
//        Calendar cal2 = Calendar.getInstance();
//        cal1.setTime(date1);
//        cal2.setTime(date2);
//
//        if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) {
//            return true;
//        } else if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) {
//            return false;
//        } else {
//            return cal1.get(Calendar.MONTH) > cal2.get(Calendar.MONTH);
//        }
//    }
//
//    // 获取指定房间和月份的所有记录
//    private List<KtParam1> getRecordsByRoomAndMonth(String roomNumber, String month) {
//        // 这里需要实现从数据库获取指定房间和月份的所有记录的逻辑
//        // 可以通过调用Mapper方法实现
//        Date date=DateUtils.getFirstDayOfMonth( month);
//        return billingMapper.selectRecordsByRoomAndMonth(roomNumber, date);
//    }


    /**
     * 合并两个 VO 对象的字段，若不一致则用逗号拼接
     */
//    private <T> void mergeFields(BillingVO target, BillingVO source, Function<BillingVO, T> getter, BiConsumer<BillingVO, T> setter) {
//        T value1 = getter.apply(target);
//        T value2 = getter.apply(source);
//
//        if (value1 == null && value2 != null) {
//            setter.accept(target, value2);
//        } else if (value2 != null && !value1.equals(value2)) {
//            if (value1 instanceof String && value2 instanceof String) {
//                String combined = ((String) value1) + "," + ((String) value2);
//                setter.accept(target, (T) combined);
//            }
//        }
//    }
//
//
//    //工具类通过khbh查询所有电表数据
//    public List<BillingVO> Ccompute(Date selectTime,KhbhDbbh kd) {
//        List<QldbzymxPO> poList = billingMapper.selectQldbzymx(kd);
//        LocalDate now = convertToLocalDate(selectTime);
//        List<BillingVO> result = new ArrayList<>();
//        for (QldbzymxPO po : poList) {
//            result.add(processBilling(po, now));
//        }
//        return result;
//    }

    // 判断两个日期是否在同一个月


    public BillingVO processBilling(QldbzymxPO po, LocalDate now) {
        // 处理入住时间匹配上个月的情况
        LocalDate poDate = convertToLocalDate(po.getQysj());
        LocalDate poDate1 = convertToLocalDate(po.getTysj());
        if (isSameYearAndMonth(poDate, now) && poDate1 != null) {
            BigDecimal c = po.getCsdl();
            //
            MouthReadPO po1 = billingMapper.selectMouthRead(po.getDbbh());
            BigDecimal b = po1.getMouthRead();
            Date t1 = po.getQysj();
            Date t2 = po1.getTimestamp();
            BigDecimal zzdl = b.subtract(c);
            BigDecimal a = zzdl.multiply(po.getDbbl());
            log.info("当月结算（入住）：" + zzdl);

            return createBillingVO(po, a,b,c,t1,t2);
        }

        // 处理退租时间匹配上个月的情况
        if (isSameYearAndMonth(poDate1, now) && notSameYearAndMonth(poDate, now)) {
            BigDecimal b = po.getZzdl();
            MouthReadPO po1 = billingMapper.selectMouthRead1(po.getDbbh());
            BigDecimal c = po1.getMouthRead();
            Date t1 = po1.getTimestamp();
            Date t2 = po.getTysj();
            BigDecimal dl = b.subtract(c);
            BigDecimal a = dl.multiply(po.getDbbl());
            log.info("当月结算（退宿）：" + a);
            return createBillingVO(po, a,b,c,t1,t2);
        }

        // 可选：同时满足入住和退宿都在上个月的情况处理
        if (isSameYearAndMonth(poDate, now) && isSameYearAndMonth(poDate1, now)) {
            // 特殊情况处理逻辑可在此添加
            BigDecimal c=po.getCsdl();
            BigDecimal b=po.getZzdl();
            Date t1=po.getQysj();
            Date t2=po.getTysj();
            BigDecimal dl=b.subtract(c);
            BigDecimal a = dl.multiply(po.getDbbl());
            log.info("当月结算（入住+退宿）：" + a);
            return createBillingVO(po, a,b,c,t1,t2);
        }

        //当月
        MouthReadPO po1 = billingMapper.selectMouthRead(po.getDbbh());
         //上月
        MouthReadPO po2 = billingMapper.selectMouthRead1(po.getDbbh());
        BigDecimal c=po2.getMouthRead();
        Date t1=po1.getTimestamp();
        Date t2=po2.getTimestamp();
        BigDecimal b=po1.getMouthRead();
        BigDecimal dl=b.subtract(c);
        BigDecimal a = dl.multiply(po.getDbbl());
        log.info("当月结算（入住+退宿）：" + a);
        return createBillingVO(po, a,b,c,t1,t2);
    }


    // 工具方法：比较年份与月份是否一致
    private boolean isSameYearAndMonth(LocalDate date1, LocalDate date2) {
        return date1 != null && date2 != null
                && date1.getYear() == date2.getYear()
                && date1.getMonth() == date2.getMonth();
    }

    private boolean notSameYearAndMonth(LocalDate date1, LocalDate date2) {
        return date1 != null && date2 != null
                && date1.getYear() != date2.getYear()
                && date1.getMonth() != date2.getMonth();
    }

    // 工具方法：将 Date 转换为 LocalDate
    private LocalDate convertToLocalDate(Date date) {
        return date != null ? date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() : null;
    }

    // 构建返回对象
    private BillingVO createBillingVO(QldbzymxPO po, BigDecimal zzdl, BigDecimal b,BigDecimal c,Date t1,Date t2) {
        BillingVO billingVO = new BillingVO();
        billingVO.setZzdl(zzdl);
        billingVO.setQymc(po.getQymc());
        billingVO.setKhbh(po.getKhbh());
        billingVO.setZt(po.getZt());
        billingVO.setFjh(po.getFjh());
        billingVO.setDbbh(po.getDbbh());
        billingVO.setC(c);
        billingVO.setB(b);
        billingVO.setDbdj(po.getDfdj());
        billingVO.setMagnification(po.getDbbl());
        String dateRange = formatTwoDates(t1, t2);
        billingVO.setZq(dateRange);
        return billingVO;
    }

//    //  工具方法：将 LocalDate 转换为 Date
//    public static Date localDateToDate(LocalDate localDate) {
//        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
//    }
//
//
//    private List<TenantBillingVO> mergeBillingVos(List<BillingVO> billingVOs) {
//        if (billingVOs == null || billingVOs.isEmpty()) {
//            return Collections.emptyList();
//        }
//
//        return billingVOs.stream()
//                .collect(Collectors.groupingBy(BillingVO::getKhbh,
//                        Collectors.mapping(Function.identity(), Collectors.toList())))
//                .values().stream()
//                .map(this::convertToTenantBillingVO)
//                .collect(Collectors.toList());
//    }

//    private TenantBillingVO convertToTenantBillingVO(List<BillingVO> group) {
//        TenantBillingVO tenantVO = new TenantBillingVO();
//        Map<String, Object> mergedFields = new HashMap<>();
//
//        // 合并通用字段
//        mergeStringField(group, BillingVO::getZt, "zt", mergedFields);
//        mergeStringField(group, BillingVO::getQymc, "qymc", mergedFields);
//        mergeStringField(group, BillingVO::getFjh, "fjh", mergedFields);
//
//        tenantVO.setZt(group.get(0).getZt());
//        tenantVO.setQymc(group.get(0).getQymc());
//        tenantVO.setKhbh(group.get(0).getKhbh());
//        tenantVO.setFjh((String) mergedFields.get("fjh"));
//        BigDecimal totalAcount = group.stream()
//                .map(BillingVO::getZzdl)
//                .filter(Objects::nonNull)
//                .reduce(BigDecimal.ZERO, BigDecimal::add);
//        tenantVO.setAcount(totalAcount);
//        tenantVO.setZq(group.get(0).getZq());
//        tenantVO.setMount(BigDecimal.ZERO);
//        tenantVO.setMount1(BigDecimal.ZERO);
//        tenantVO.setMount2(BigDecimal.ZERO);
//        tenantVO.setZacount(
//                totalAcount
//                        .add(tenantVO.getMount())
//                        .add(tenantVO.getMount1())
//                        .add(tenantVO.getMount2())
//        );
//
//        ZtPo ztPo=billingMapper.selectck((String) mergedFields.get("zt"));
//        tenantVO.setSkr(ztPo.getSkr());
//        tenantVO.setKhh(ztPo.getKhh());
//        tenantVO.setRmbzh(ztPo.getRmbzh());
//
//        // 构建电表列表
//        List<ElectricMeter> meters = group.stream().map(bvo -> {
//            ElectricMeter meter = new ElectricMeter();
//            meter.setDbbh(bvo.getDbbh());
//            meter.setC(bvo.getC());
//            meter.setB(bvo.getB());
//            meter.setZzdl(bvo.getZzdl());
//            meter.setMagnification(bvo.getMagnification());
//            meter.setDbdj(bvo.getDbdj());
//            meter.setE(bvo.getZzdl().multiply(bvo.getMagnification()));
//            meter.setMount(bvo.getZzdl().multiply(bvo.getMagnification()).multiply(bvo.getDbdj()));
//            return meter;
//        }).collect(Collectors.toList());
//
//
//        tenantVO.setElectricMeters(meters);
//
//        return tenantVO;
//    }

//    private void mergeStringField(List<BillingVO> list, Function<BillingVO, String> getter, String key, Map<String, Object> result) {
//        Set<String> values = list.stream()
//                .map(getter)
//                .filter(Objects::nonNull)
//                .collect(Collectors.toSet());
//
//        if (values.size() == 1) {
//            result.put(key, values.iterator().next());
//        } else {
//            result.put(key, String.join(",", values));
//        }
//    }

    public static String formatTwoDates(Date dateStart, Date dateEnd) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
        return sdf.format(dateStart) + "-" + sdf.format(dateEnd);
    }


}
